package com.block.product.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.block.common.annotate.RedisLock;
import com.block.common.constant.RedisKeyConstant;
import com.block.common.enums.ChargeTypeEnum;
import com.block.common.model.dto.CountInfoDTO;
import com.block.common.service.IChannelCommonService;
import com.block.db.entity.ProductBaseInfo;
import com.block.db.entity.ProductOnlieInfo;
import com.block.db.entity.ProductProfitInfo;
import com.block.db.mapper.ProductProfitInfoMapper;
import com.block.product.service.IProductBaseInfoService;
import com.block.product.service.IProductOnlieInfoService;
import com.block.product.service.IProductProfitInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 产品收益信息 服务实现类
 * </p>
 *
 * @author 
 * @since 2023-09-04
 */
@Service
public class ProductProfitInfoServiceImpl extends ServiceImpl<ProductProfitInfoMapper, ProductProfitInfo> implements IProductProfitInfoService {

    @Autowired
    IProductOnlieInfoService productOnlieInfoService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    IProductBaseInfoService productBaseInfoService;
    @Autowired
    IChannelCommonService channelCommonService;

    @Override
    @Transactional
    @RedisLock(lockName = "PRODUCT::PROFIT::RECORD", key = "#productId" )
    public void recordProductProfitInfo(Integer productId, ProductOnlieInfo productOnlieInfo, ProductBaseInfo productBaseInfo,  String nowDate, String channelCode) {

        ProductProfitInfo productProfitInfo = this.baseMapper.getEntityByIdAndDateInfoLock(productId, nowDate);
        if (ObjectUtil.isEmpty(productProfitInfo)){
            ProductProfitInfo newEntity = new ProductProfitInfo();
            newEntity.setDateInfo(nowDate);
            newEntity.setProductId(productOnlieInfo.getProductId());
            newEntity.setProductName(productOnlieInfo.getProductName());
            newEntity.setPriceAmount(productOnlieInfo.getPriceAmount());
            newEntity.setTotalUvNumber(productOnlieInfo.getUvCount());
            // 查询已经产生的uv量
            Integer hadUvNumber = this.baseMapper.getUvNumberByProductId(productId);
            hadUvNumber = ObjectUtil.isEmpty(hadUvNumber)?0:hadUvNumber;
            newEntity.setHadUvNumber(hadUvNumber);

            boolean save = this.save(newEntity);
            if (!save){
                return;
            }
            productProfitInfo = this.baseMapper.getEntityByIdAndDateInfoLock(productId, nowDate);
        }

        Integer totalUvNumber = productProfitInfo.getDayUvNumber() + 1;
        Integer hasUvNumber = productProfitInfo.getHadUvNumber()+ 1;

        ProductProfitInfo updateEntity = new ProductProfitInfo();
        updateEntity.setId(productProfitInfo.getId());
        updateEntity.setProductId(productProfitInfo.getProductId());
        updateEntity.setDayUvNumber(totalUvNumber);
        updateEntity.setHadUvNumber(hasUvNumber);

        CountInfoDTO countInfoDTO = new CountInfoDTO(channelCode);

        // 通过点击统计注册/uv计价的产品uv和收益
        if (ObjectUtil.equals(productBaseInfo.getChargeType(), ChargeTypeEnum.UNION.getValue())){
            countInfoDTO.setProUvCount(1);
            countInfoDTO.setProUvProfit(productOnlieInfo.getPriceAmount());

            BigDecimal totalAmount = NumberUtil.add(productOnlieInfo.getPriceAmount(), productProfitInfo.getDayProfit());
            updateEntity.setDayProfit(totalAmount);
        }

        // 通过点击统计注册/uv计价的产品uv和收益
        if (ObjectUtil.equals(productBaseInfo.getChargeType(), ChargeTypeEnum.REG.getValue())){
            countInfoDTO.setProUvCount(1);
        }

        if (ObjectUtil.equals(productBaseInfo.getChargeType(), ChargeTypeEnum.UV.getValue())){


            countInfoDTO.setProUvProfit(productOnlieInfo.getPriceAmount());
            countInfoDTO.setProUvCountUv(1);// uv的数量
            countInfoDTO.setProUvCount(1);
        }

        // 查询
        Integer remainNumber = productProfitInfo.getTotalUvNumber() - hasUvNumber;

        String redisKey = StrUtil.format(RedisKeyConstant.PRODUCT_UV_REMAIN_COUNT_KEY, nowDate, productId);
        stringRedisTemplate.opsForValue().set(redisKey, String.valueOf(remainNumber), 12, TimeUnit.HOURS);

        // 统计点击与收益
        channelCommonService.updateChannelCount(countInfoDTO);

        this.updateById(updateEntity);
    }
}
